package com.example.demo.service.impl;

import com.example.demo.dto.Admin.AdminUserCreationRequestDto;
import com.example.demo.dto.Admin.AdminUserUpdateRequestDto;
import com.example.demo.dto.UserUpdateRequestDto;
import com.example.demo.entity.User;
import com.example.demo.repository.AdminRepository; // <--- 新增导入, 用于账号冲突检查
import com.example.demo.repository.BookkeepingRepository;
import com.example.demo.repository.UserRepository;
import com.example.demo.service.UserService;
import org.slf4j.Logger; // <--- 新增导入
import org.slf4j.LoggerFactory; // <--- 新增导入
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.util.StringUtils; // <--- 新增导入

import java.util.List;
import java.util.Optional; // <--- 新增导入

@Service
public class UserServiceImpl implements UserService {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class); // <--- 新增日志记录器

    private final UserRepository userRepository;
    private final BookkeepingRepository bookkeepingRepository;
    private final PasswordEncoder passwordEncoder;
    private final AdminRepository adminRepository; // <--- 注入 AdminRepository 用于查重

    @Autowired
    public UserServiceImpl(UserRepository userRepository,
                           BookkeepingRepository bookkeepingRepository,
                           @Qualifier("bCryptPasswordEncoder") PasswordEncoder passwordEncoder,
                           AdminRepository adminRepository) { // <--- 添加 AdminRepository 注入
        this.userRepository = userRepository;
        this.bookkeepingRepository = bookkeepingRepository;
        this.passwordEncoder = passwordEncoder;
        this.adminRepository = adminRepository; // <--- 初始化 AdminRepository
    }

    @Override
    @Transactional
    public User register(User userToRegister) {
        log.info("尝试注册新用户，账号: {}", userToRegister.getAccount());
        if (userRepository.existsByAccount(userToRegister.getAccount())) {
            log.warn("注册失败：账号 {} 已存在。", userToRegister.getAccount());
            throw new IllegalArgumentException("账号已存在: " + userToRegister.getAccount());
        }
        if (adminRepository.existsByAccount((userToRegister.getAccount()))) { // <--- 检查管理员账号冲突
            log.warn("注册失败：账号 {} 已被管理员占用。", userToRegister.getAccount());
            throw new IllegalArgumentException("账号已被管理员占用: " + userToRegister.getAccount());
        }

        userToRegister.setPassword(passwordEncoder.encode(userToRegister.getPassword()));
        userToRegister.setBookCount(0);
        User savedUser = userRepository.save(userToRegister);
        log.info("用户 {} (ID: {}) 注册成功。", savedUser.getAccount(), savedUser.getId());
        return savedUser;
    }

    @Override
    public User login(String account, String password) {
        log.info("用户 {} 尝试登录。", account);
        User user = userRepository.findByAccount(account)
                .orElseThrow(() -> {
                    log.warn("登录失败：用户 {} 不存在。", account);
                    return new EntityNotFoundException("用户不存在: " + account);
                });
        if (!passwordEncoder.matches(password, user.getPassword())) {
            log.warn("登录失败：用户 {} 密码错误。", account);
            throw new IllegalArgumentException("密码错误");
        }
        log.info("用户 {} 登录成功。", account);
        return user;
    }

    @Override
    public User getUserById(Integer id) {
        log.debug("根据 ID {} 查询用户。", id);
        return userRepository.findById(id)
                .orElseThrow(() -> {
                    log.warn("查询失败：用户 ID {} 未找到。", id);
                    return new EntityNotFoundException("用户ID未找到: " + id);
                });
    }

    @Override
    public User getUserByAccount(String account) {
        log.debug("根据账号 {} 查询用户。", account);
        return userRepository.findByAccount(account)
                .orElseThrow(() -> {
                    log.warn("查询失败：用户账号 {} 未找到。", account);
                    return new EntityNotFoundException("用户账号未找到: " + account);
                });
    }

    @Override
    public List<User> getAllUsers() {
        log.info("获取所有用户列表。");
        return userRepository.findAll();
    }

    @Override
    @Transactional
    public User updateUser(Integer id, UserUpdateRequestDto userUpdateRequestDto) {
        log.info("用户 ID {} 请求更新个人信息。", id);
        User user = getUserById(id);
        String originalAccount = user.getAccount();
        boolean changed = false;

        // 检查账号是否更改
        if (userUpdateRequestDto.getAccount() != null && !userUpdateRequestDto.getAccount().equals(user.getAccount())) {
            String newAccount = userUpdateRequestDto.getAccount();
            log.info("用户 {} (ID: {}) 尝试将账号更新为: {}", originalAccount, id, newAccount);
            if (userRepository.existsByAccount(newAccount)) {
                String errorMsg = "更新失败：账号 " + newAccount + " 已被其他用户使用。";
                log.warn(errorMsg);
                throw new IllegalArgumentException(errorMsg);
            }
            if (adminRepository.existsByAccount(newAccount)) { // <--- 检查管理员账号冲突
                String errorMsg = "更新失败：账号 " + newAccount + " 已被管理员使用。";
                log.warn(errorMsg);
                throw new IllegalArgumentException(errorMsg);
            }
            user.setAccount(newAccount);
            log.info("用户原账号 {} (ID: {}) 已更新为 {}", originalAccount, id, newAccount);
            changed = true;
        }

        if (userUpdateRequestDto.getUsername() != null && !userUpdateRequestDto.getUsername().equals(user.getUsername())) {
            user.setUsername(userUpdateRequestDto.getUsername());
            log.info("用户 {} (ID: {}) 的用户名已更新。", user.getAccount(), id);
            changed = true;
        }
        if (userUpdateRequestDto.getAvatar() != null && !userUpdateRequestDto.getAvatar().equals(user.getAvatar())) {
            user.setAvatar(userUpdateRequestDto.getAvatar());
            log.info("用户 {} (ID: {}) 的头像已更新。", user.getAccount(), id);
            changed = true;
        }

        if(changed) {
            User savedUser = userRepository.save(user);
            log.info("用户 {} (ID: {}) 的个人信息更新成功。", savedUser.getAccount(), id);
            return savedUser;
        } else {
            log.info("用户 {} (ID: {}) 未提供有效的更新信息。", user.getAccount(), id);
            return user;
        }
    }

    @Override
    @Transactional
    public User changePassword(Integer userId, String oldPassword, String newPassword) {
        log.info("用户 ID {} 请求修改密码。", userId);
        User user = getUserById(userId);
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            log.warn("用户 {} (ID: {}) 修改密码失败：旧密码不正确。", user.getAccount(), userId);
            throw new IllegalArgumentException("旧密码不正确");
        }
        user.setPassword(passwordEncoder.encode(newPassword));
        User savedUser = userRepository.save(user);
        log.info("用户 {} (ID: {}) 修改密码成功。", savedUser.getAccount(), userId);
        return savedUser;
    }

    @Override
    @Transactional
    public void deleteUser(Integer id) {
        log.info("请求删除用户 ID: {}", id);
        User user = getUserById(id); // 会在找不到时抛出异常
        String deletedAccount = user.getAccount();
        userRepository.delete(user);
        log.info("用户 {} (ID: {}) 已被删除。", deletedAccount, id);
    }

    @Override
    @Transactional
    public void incrementBookCount(Integer userId) {
        log.debug("增加用户 ID {} 的记账数量。", userId);
        User user = getUserById(userId);
        user.setBookCount(user.getBookCount() + 1);
        userRepository.save(user); // updateTime 会自动更新
    }

    @Override
    @Transactional
    public void decrementBookCount(Integer userId) {
        log.debug("减少用户 ID {} 的记账数量。", userId);
        User user = getUserById(userId);
        int currentCount = user.getBookCount();
        if (currentCount > 0) {
            user.setBookCount(currentCount - 1);
            userRepository.save(user); // updateTime 会自动更新
        } else {
            log.warn("尝试减少用户 ID {} 的记账数量，但当前数量已为 0。", userId);
        }
    }

    // --- 管理员操作实现 ---
    @Override
    @Transactional
    public User createUserByAdmin(AdminUserCreationRequestDto creationRequestDto) {
        log.info("管理员尝试添加新用户，账号: {}", creationRequestDto.getAccount());
        if (userRepository.existsByAccount(creationRequestDto.getAccount())) {
            String errorMsg = "管理员添加用户失败：账号 '" + creationRequestDto.getAccount() + "' 已存在。";
            log.warn(errorMsg);
            throw new IllegalArgumentException(errorMsg);
        }
        if (adminRepository.existsByAccount(creationRequestDto.getAccount())) { // <--- 检查管理员账号冲突
            String errorMsg = "管理员添加用户失败：账号 '" + creationRequestDto.getAccount() + "' 已被管理员占用。";
            log.warn(errorMsg);
            throw new IllegalArgumentException(errorMsg);
        }

        User newUser = new User();
        newUser.setAccount(creationRequestDto.getAccount());

        if (StringUtils.hasText(creationRequestDto.getUsername())) {
            newUser.setUsername(creationRequestDto.getUsername());
        } else {
            newUser.setUsername(creationRequestDto.getAccount()); // 默认用户名同账号
            log.debug("新用户 {} 将使用账号作为默认用户名。", newUser.getAccount());
        }

        newUser.setPassword(passwordEncoder.encode(creationRequestDto.getPassword()));
        newUser.setAvatar(creationRequestDto.getAvatar()); // 可以为 null 或空字符串
        newUser.setBookCount(0);

        User savedUser = userRepository.save(newUser);
        log.info("管理员成功添加新用户 {} (ID: {})。", savedUser.getAccount(), savedUser.getId());
        return savedUser;
    }

    @Override
    @Transactional
    public void deleteUserByAdmin(String account) {
        log.info("管理员尝试删除用户，账号: {}", account);
        User userToDelete = userRepository.findByAccount(account)
                .orElseThrow(() -> {
                    log.warn("管理员删除用户失败：未找到账号为 '{}' 的用户。", account);
                    return new EntityNotFoundException("无法删除：未找到账号为 '" + account + "' 的用户。");
                });
        Integer deletedId = userToDelete.getId();
        userRepository.delete(userToDelete);
        log.info("管理员成功删除用户 {} (ID: {})。", account, deletedId);
    }

    @Override
    @Transactional
    public User updateUserByAdmin(String account, AdminUserUpdateRequestDto updateRequestDto) {
        log.info("管理员尝试更新用户 {} 的信息。", account);
        String finalAccount = account;
        User userToUpdate = userRepository.findByAccount(account)
                .orElseThrow(() -> {
                    log.warn("管理员更新用户信息失败：未找到账号为 '{}' 的用户。", finalAccount);
                    return new EntityNotFoundException("无法更新：未找到账号为 '" + finalAccount + "' 的用户。");
                });

        boolean updated = false;
        String originalAccountForLog = userToUpdate.getAccount(); // Store original account for logging

        // 更新用户名
        if (updateRequestDto.getUsername() != null) { // Allow setting empty username if needed
            if (!updateRequestDto.getUsername().equals(userToUpdate.getUsername())) {
                userToUpdate.setUsername(updateRequestDto.getUsername());
                log.info("管理员更新用户 {} 的用户名为: '{}'", account, updateRequestDto.getUsername());
                updated = true;
            }
        }

        // 更新账号
        if (StringUtils.hasText(updateRequestDto.getNewAccount()) && !updateRequestDto.getNewAccount().equals(userToUpdate.getAccount())) {
            String newAccount = updateRequestDto.getNewAccount();
            log.info("管理员尝试将用户 {} 的账号更新为: {}", account, newAccount);
            if (userRepository.existsByAccount(newAccount)) {
                String errorMsg = "管理员更新用户失败：新账号 '" + newAccount + "' 已被其他用户使用。";
                log.warn(errorMsg);
                throw new IllegalArgumentException(errorMsg);
            }
            if (adminRepository.existsByAccount(newAccount)) { // <--- 检查管理员账号冲突
                String errorMsg = "管理员更新用户失败：新账号 '" + newAccount + "' 已被管理员使用。";
                log.warn(errorMsg);
                throw new IllegalArgumentException(errorMsg);
            }
            userToUpdate.setAccount(newAccount);
            log.info("管理员成功将用户原账号 {} 更新为 {}", originalAccountForLog, newAccount);
            account = newAccount; // Update account variable for subsequent logs in this transaction
            updated = true;
        }

        // 更新密码 - 使用 getNewPassword()
        if (StringUtils.hasText(updateRequestDto.getNewPassword())) {
            userToUpdate.setPassword(passwordEncoder.encode(updateRequestDto.getNewPassword()));
            log.info("管理员更新了用户 {} 的密码。", account);
            updated = true;
        }

        // 更新头像
        if (updateRequestDto.getAvatar() != null) { // Allow setting empty avatar
            if (!updateRequestDto.getAvatar().equals(userToUpdate.getAvatar())) {
                userToUpdate.setAvatar(updateRequestDto.getAvatar());
                log.info("管理员更新了用户 {} 的头像。", account);
                updated = true;
            }
        }

        // 更新记账数目
        if (updateRequestDto.getBookCount() != null && !updateRequestDto.getBookCount().equals(userToUpdate.getBookCount())) {
            userToUpdate.setBookCount(updateRequestDto.getBookCount());
            log.info("管理员更新用户 {} 的记账数目为: {}", account, updateRequestDto.getBookCount());
            updated = true;
        }


        if (updated) {
            User savedUser = userRepository.save(userToUpdate);
            log.info("管理员成功更新了用户 {} 的信息。", savedUser.getAccount());
            return savedUser;
        } else {
            log.info("管理员未对用户 {} 提供有效的更新信息。", account);
            return userToUpdate;
        }
    }
}
